home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-09-08 | 48.7 KB | 1,083 lines |
- ..All lines beginning with two periods are ignored by PC-Write
- ..If you have a different word processor you need to remove these lines.
- ..Also note three coded lines just before Chapter I and at the beginning
- ..of Lass-2.man. They are directionsto PC-Write to number the pages,
- ..starting with page 1, and placing the numbers in the middle of a footer
- ..line leaving 1 blank between text and footer.
- ..If your word processor is not PC-Write, you may need to change them.
- ..Similaraly, the end of each page is marked with ALT 12 (0C), or ""
- ..My apologies, but I know no way of offering you a neat printout
- ..without these marks.
-
-
-
-
-
- LASS
-
- THE LITTLE ASSEMBLER
- for 8088 code
-
-
-
- by Dorothy R. Mooney
- (Copyright 1986, 1989)
-
-
-
-
- Table of Contents
-
- I Begin with Backup . . . . . . . . . . . . . . 1
- and general instructions for using Lass
-
- II Linking . . . . . . . . . . . . . . . . . 5
-
- III End of File . . . . . . . . . . . . . . . . . 6
-
- IV Source Code Syntax . . . . . . . . . . . . . . 8
-
- V Mnemonic Table . . . . . . . . . . . . . . . . 13
-
- VI Pseudo Ops . . . . . . . . . . . . . . . . . 21
-
- VII Error Messages . . . . . . . . . . . . . . . . 23
-
- VIII Basic Linking . . . . . . . . . . . . . . . . 26
-
- .N:1
- .F:
- .F:...Page $$$...
-
- Chapter I
- Begin with Backup
-
- Before printing and reading this document, you should have
- backed up the Lass disk. If not, do it now. Reordering and
- waiting to replace a tromped on disk when you have your source
- code all ready to assemble will not make your week, believe me !
- Files are:
-
- Lass.txt a short note to get you started
- Lass-1.man the manual of instructions
- Lass-2.man
- LASS.com the Little Assembler
- L-Ruler.asm a PC_Write file
-
- That ruler file is one I use for writing source code with
- PC-Write. If you have some other word processor it will be of
- no use to you: ignore it. To use it with PC-Write you need only
- rename the file Ruler.asm. A quick look with PC-Write's editor
- will show you what it will do.
-
- Lass translates your 8088 source code into machine lanuage,
- creating a .COM program. Such a program can be any size up to
- 65,535 bytes in length, or 64K, the size of one segment. The
- source code for a long program may burst the limits of your word
- processor, but you can write and file it into more than one
- source file, and Lass will will be able to link the parts
- together into one program.
-
- Once you have written your source code all you need to do
- to run Lass, assuming Lass.com is on the disk in drive A, is to
- enter drive A and type:
-
- A> lass and press the Enter key.
-
- When Lass has been loaded into memory, the screen will
- fill with text. Follow the prompts on the screen. When you are
- asked for a drive, enter the drive letter. Any letter from A to
- E will be accepted. Once all questions are answered, Lass gets
- to work. When assembly is complete a message will appear on the
- screen, perhaps "There were 5 assembly errors". Since an error
- may be counted during each pass, most of them will be counted
- twice. When the message "There were No assembly errors"
- appears, you are ready to try running the program.
-
- Since Lass loads completely into memory, if you keep Lass
- on a disk by itself you can remove it as soon as the first
- message appears on the screen, and replace it with either the
- disk holding your source code, or a separate disk to receive the
- object (.COM) file. As the program runs you will be asked which
- drive holds the source file(s) and which will receive the object
- file, so they may be on separate disks if you wish. Note that
- once assembly has started, the object (.COM) file must NOT be
- moved. If you are using Llinker.asm, it too must stay in one
- place, so Lass assumes that the two immovables are on the same
- disk in the same drive. If this is not also the source disk,
-
- transfer Llinker.asm to the new object disk before entering
- LASS.com. Llinker.asm is discussed in Chapter II.
-
- If you have as much as 128K in your computer you should
- have no difficulty with LASS.com. If Lass hangs up during
- assembly you may have too many labels. See the discussion under
- LABELS in Chapter IV.
-
- If you have just one drive your problem will be space for
- your source files. You can still use a Llinker.asm file, but
- all the source files must be on that one disk, along with space
- for the new object file .COM. If you answered "y" when asked if
- you want a listing file, more than half the disk must be free
- since the .LST file will be longer than the source file(s). (The
- listing file lists each line of source code along with the
- object code for the line. Useful in debugging a long program.)
-
- When you are asked for the name of your source file, if you
- have just one source code file, enter the filename, with or
- without an extension. You may use any extension you wish, but if
- you enter none, the extension .ASM will be assumed. If there is
- more than one source file, you must use a Llinker file. Since
- LLINKER.ASM is the default, you need only press Enter to choose
- this option. Lass will look for the Llinker file on the disk
- you specify for the object file.
-
- For the object file, the default is your source filename,
- or the first name in the Llinker file, with the extension .COM.
- If this is what you want, merely press Enter. If not, enter the
- name you do want, with or without extension. If you enter just
- a filename, the extension .COM will be added, since DOS will not
- run your new program without it.
-
- You will also be asked if you want listings. If you ask for
- a Pass One listing, the decimal line number and source code for
- each line will be displayed on the screen. This slows down the
- assembly, and Error messages also show the line number, so you
- can do without this listing. However, if an error causes the
- computer to hang up during assembly, use the screen listings on
- your next try to help you find the error.
-
- For a Pass Two listing each code line is preceded by the
- hexadecimal offset address of the line and up to six bytes of
- the object code for the line. The listing may be printed, sent
- to the screen, or filed in anĀ·.LST file on disk. If you choose
- the Print option it is wise to do a trial assembly first without
- listing to make sure that there are no assembly errors to cause
- you to do it all over again. Printing takes time. If you
- choose to have the listing sent to a disk file, check disk
- space: the .LST file will go onto the same disk with the .COM
- (object) file and it will take up to half again as much space as
- the source file(s). There will be just one (long) file with the
- same name as the .COM file, but with the extension .LST.
-
- You will also be asked if you wish a Label Cross Reference
- file, to be written to disk. Every label is listed with its
- address and the address of up to 10 locations where the label
-
- was used in an operand. There is a pause before filing to allow
- you to change to a new disk, so you need not cross your fingers
- and hope it will not overflow. The file will be given the same
- name as the object file, but with the extension .REF.
-
- Lass makes two passes through the source code. During Pass
- One, a count is made of the object code bytes that will be
- needed and a Label Table is created. This table lists each
- label in your source code and uses the object code byte count as
- the address where the label is to be found. Since a .COM
- program may be loaded by DOS anywhere in memory, the location of
- a particular label may be found only in relation to the first
- code byte. That is, if the byte count is 297h when the label
- Clear_Screen is found, 297h is the offset address of that label.
- Or, more simply, the offset. (See EQU in the chapter on op
- mnemonics for the handling of those labels.)
-
- The second pass generates the code and files it onto a
- disk, using the offset addresses in the label table to translate
- each label used in an operand into a number.
-
- If errors are found during assembly, a message is shown on
- the screen. For most errors you can make a note, continue with
- the assembly and correct the source code after you have
- collected all the errors. Then try again. When you get the
- message "No assembly errors" you have a perfect .COM program.
- Perfect, that is, so far as syntax is concerned. If you want a
- listing now is the time to call for it, making a final assembly
- run when you know time and paper will not be wasted.
-
- Chapter II
- Linking
-
- When there is more than one source file, Lass needs some
- way of finding them all, and in the right order. A special
- file, LLINKER.ASM is used. It is nothing more then a list of
- all your source files. If you have source code for more than
- one program on your disk and want to keep more than one
- llinker file, rename the one you are not using, perhaps LL-1.
-
- Using your word processor, make a list of all source files,
- in the order you wish to have them assembled. Any mix of upper
- and lower case letters may be used. There must be nothing else
- in the file, and the file must end with an end of file mark
- (EOF) like any other source file. (See the next chapter for a
- discussion of the end of file mark.) For example:
-
- DATA.asm+
- CODE.asm+
- Code2.asm+
- *Insert disk with MoreCode & LastFile+
- MoreCode.asm+
- LASTFILE.asm+
- (EOF)
-
- Note that each filename is flush left, each filename is on
- a separate line and ends with a plus sign, and there are no
- comments. The asterisk at the start of a line signals to Lass
- that there is to be a pause. The line itself is the message you
- wish to have displayed on the screen. The program will wait for
- you to change the source disk and press enter. Note that the
- message line, too, ands with a plus sign.
-
- Chapter III
- End of File
-
- Lass does not have sense enough to stop if there is no end
- of file mark on your source or LLinker file, but will keep
- trying to parse whatever else is on the disk. Disaster! This
- important mark is simply the hexadecimal number 1A, or decimal
- 26. It will appear on the screen as a small, right facing
- arrow. (This is not the same arrow produced by the escape key,
- which is left facing.)
-
- Using your word processor, check the end of the file. If no
- little right facing arrow appears, try adding it. Hold down the
- alternate key (Alt) and press 2 and then 6 on the number pad.
- When you release the Alt key the arrow should appear. If you
- have written your code with Edlin, the marker will be there. If
- you load your file into Edlin and then enter 'e', Edlin will add
- the marker if it is not already there. Note that Edlin also
- creates a .BAK file which is as long as the original, so watch
- your disk space.
-
- If there seems to be no other way out, write a short file
- (one word will do) with Edlin and End (press 'e'). Then append
- it to the end of your code file, using your word processor or
- the DOS copy command. (See your DOS manual.) Of course, if you
- write this file before you write your source code, you can load
- it into your word processor, rename it, and then write the code.
- Be careful not to erase the marker.
-
- Chapter IV
- Source Code Syntax
-
- To write your source code, use a word processor, or, for
- short programs, Edlin. If you have not read the End of File
- chapter, do so now. It is also important to know that Lass will
- recognize only ascii text, tabs, carriage return and line feed
- (set by the Enter key) and that EOF mark. A period as the first
- character of a line will cause the whole line to be ignored.
-
- Each operation, consisting of an op code and any operands
- it needs, must be on a separate line. No line of code may be
- more than 78 characters long (plus carriage return), and the
- first character in the line must be a space or tab, a semicolon,
- or else the first letter of a label. If you use PC-Write, you
- may use comment lines starting with ".." (two periods) or
- printer commands starting with ".", one period, with full
- confidence that Lass will ignore them. The order of
-
- LABEL OP OPERAND, OPERAND
-
- must be maintained, and the parts must be separated by spaces or
- tabs or, in the case of the two operands, by a comma. Except
- for the label, the column position doesn't matter. A semicolon
- (;) or a colon (:) after a label will cause the rest of the line
- to be ignored.
-
- Code may be written in any combination of upper and lower
- case: Mov, MOV, and moV will all be accepted. However, Lass is
- quite rigid and unforgiving of spelling errors. But then, so is
- your eye. You are used to seeing a word all of a piece, without
- sp ace s int he mid dleofit. You are smart enough to make sense
- out of that sentence, but Lass cannot make sense out of M OV or
- [ bx + 03]. For operands, a comma is used as a separator, and
- must fit tightly against the operand it follows, but a space or
- so before the next operand can be assimilated. For instance,
- the following are ok:
-
- mov ax,3
- mov ax, 16d
- movB [bx], Labelnn
- but NOT:
- add ax3
- sub ax 15
- mov ax ,Anything
-
- Since the program is limited to one segment, such pseudo
- ops as "ASSUME" or "PROC", used in creating .EXE files, are not
- needed and will be ignored if they are found.
-
- LABELS
- ~~~~~~
- LASS.com uses a full segment (64K) in memory to hold up to
- 2048 (decimal) labels for a program. In case this is not enough
- for your source code, check out the $+ alternative under
- conditional jumps (directly after IRET below).
-
- The first character of a label must be the first character
- on the line. If a space manages to creep in first, it will
- cause Lass to try to make an op code of the label, to everyone's
- confusion. Labels may be as long as 32 characters, but only the
- first 10 characters will be used by Lass. Upper case and lower
- case letters will be treated as equals, so that Little_Assembler
- and LITTLE_ASSYRIAN would be taken to be the same label.
-
- The first character following a label must be a space or
- tab or a colon (:), or a carriage return. The colon will be
- taken as the end of the line, a space or tab will cause the
- assembler to continue searching for an op mnemonic.
-
- The first character of a label must be a letter, or one of
- the characters between Z and a in the ascii listing.
-
- \ ^ _ `
-
- Within a label these additional characters will be accepted:
-
- < = > ? @ ! " # % & ( ) * . /
-
- If characters above lower case z (7Bh) are used, they will
- be changed along with lower case letters by subtracting 20h.
- The line (|) or tilde (~) will become (\) or (^), but the curly
- brackets { } will become square brackets [ ] and should never be
- used. Of course other characters which are used in operands
- should not be used, such as, + - $ ' []. Lass will accept them
- with no warning in the label column, but will try to translate
- them for their special meanings if they appear in an operand.
- Note that a period in the first column will be cheerfully
- accepted but the whole line will be ignored. See the beginning
- of this chapter.
-
- Possible syntax:
-
- Second_Call equ NEW#@_CALL
- New#@_Call:
- mov AX,0
- Re/Call Mov Cx,19h
- \After_Thought
- Inc CX
-
- Not permitted:
-
- /No_Code: mov cx,0 ;"/" is forbidden in 1st position.
- ;The colon ends the line and
- ;all the code would be lost.
- Trouble+here: ;the "+" will cause confusion when
- ;CALL Trouble+here is found.
-
- There is one use of a label which will cause trouble, and
- Lass has no way of wriggling out. If a label is set by an EQU
- statement to a value below 128 (80 hex) and then used as the
- displacement within a pointer, the EQU statement absolutely must
- come at the head of the program. If Lass finds the operation
- statement first during the first pass of the assembly, she will
- not know the value so will assume a word. When the byte value
- is substituted on the second pass, the byte count will be thrown
- off - an error from which there is no return. For instance:
-
- mov al,[si+Name] ;NOT YET - Name unknown
-
- Name equ 5 ;place all EQU statements ahead
- Address equ 10 ;of any code
- ,..
- ,..
- mov al,[si+Name] ;ok, Lass now has the value
-
- OP Mnemonics
- ~~~~~~~~~~~~
- Most of the codes in your assembly language primer are
- accepted by Lass, but since all your code must be contained
- within one segment for a .COM program, far jumps or calls to
- another segment will produce an error message. 4 letter jump
- codes, such as JNAE, will cause confusion, producing errors
- which will not be found by the assembler. (See Jumps)
-
- The OP mnemonic must be preceded by a space or tab and
- followed by another space or tab. If there is no operand, an
- immediate carriage return or semicolon is accepted.
-
- OPERANDS
- ~~~~~~~~
- The first operand must be preceded by a space or tab and be
- followed immediately by a comma. If there is a space between
- the operand and the comma, the comma will be ignored and the end
- of the line assumed. There may be a space (or spaces) following
- the comma. The second operand may be followed by a space or
- tab, a semicolon, or a carriage return.
-
- When a pointer operand needs to be identified as a byte or
- word pointer, Lass looks for a B or W as part of the op
- menemonic. For instance:
-
- movB [DI],0 or INCW [varbl_1]
-
- All the register pointers are accepted, up to and including
- such monsters as [BX+DI+LongLabel]. If you are counting bytes
- for short jumps you need to be aware that [BP] will be accepted
- and translated to [BP+00], adding one more byte to what you have
- written. There must be no spaces within the [] and the whole
- operand must be within the two brackets. -5[BX] instead of [BX-
- 5] will result in an error. Acceptable label addresses include
- [Kentucky+36h] or [BX+Kentucky] but not [BX+Kentucky+01]. And
- note that [SI-BX] is not acceptable: registers must be added.
- Of course, you can get around this restriction by putting a
- negative number into BX.
-
- Lass treats numbers and numbers translated from labels in
- exactly the same way:
-
- For numbers:
-
- mov ax,3000h ;an immediate number into AX
- mov ax,[3000h] ;AX takes the number stored
- ;at memory location 3000h
- Similarly:
-
- mov si,Pennies ;SI takes the immediate number
- ;represented by "Pennies"
- mov ax,[Pennies] ;AX takes a number from the
- ;memory location "Pennies"
- mov cx,[si] ;and now CX = AX
-
- NUMBERS
- ~~~~~~~
- Lass does not speak in octaves nor in binary, but either
- decimal or hexadecimal numbers will be accepted. In either case,
- the number must start with a decimal digit, so FFh, for
- instance, must be written as 0FFh. A decimal number will be
- accepted with or without a 'D' at the end, but a hexidecimal
- number must usually terminate with 'H'. 0F would be processed as
- hexidecimal, but 0D would be taken for a decimal 0. Single
- ascii characters are accepted, but no binary numbers, please.
-
- acceptable:
- Mov ax,65 ;decimal
- incB [bx+15d] ;decimal
- add cx,41h ;hexadecimal
- sub al,'0' ;ascii
- and al,03 ;instead of binary 0011
- NOT acceptable:
- and al,1D ;D = decimal
- mov cl,FFh ;will be mistaken for a label
- mov ax,'BA' ;2 ascii characters
- and al,0011b ;Lass reads 11B hexadecimal
-
- Number length is limited by the capacity of a byte or word.
- With a short jump or a 1 byte displacement, which can be either
- positive or negative, the number must be within the range of
- -128 to +127 decimal (80h to 0 to 7Fh). However, an immediate
- number is assumed to be positive and may be as large as 255
- decimal (0FFh). A word displacement, such as [BX-645], may range
- from -32,768 to +32,767 (0FFFFh to 7FFFh). An immediate word may
- hold a number as large as 65,535 (0FFFFh).
-
- If you have not met hexadecimal numbers before, 0FFh as
- either -128 or 255 may seem like a bit of slick dealing. The
- difference comes because a number that has no sign may use each
- of the 8 bits in the byte, but for a signed number, the leftmost
- bit is used to signal positive (0) or negative (1), leaving just
- seven bits for the number itself.
-
- COMMENTS
- ~~~~~~~~
- A comment may start at any place on the line, and should
- start with a semicolon (;). Everything beyond the semicolon will
- be ignored by the assembler. If a comment continues on a second
- line, it must be preceded by another semicolon. As you get used
- to using Lass you will find that often the semicolon is not
- necessary. The assembler knows how many operands belong to an
- op code and will ignore anything beyond them on the line. Do
- not count on this blindly - RET, for instance, may have no
- operand or a number, so Lass can't know to end the line without
- a marker.
-
- Do not use ' in a comment. The reverse quote, (`) may be
- used, or the double quote ("), but the normal single quote will
- cause the remaining portion of a comment to be listed in upper
- case letters.
-
- Since many print programs take a period to signal a command
- line, Lass will treat any line which starts with a period as
- non-existent. It will not even be counted. The period must be
- in the first column, though, or it will be taken for an unknown
- operand.
-
- ADDRESSING MODES
- ~~~~~~~~~~~~~~~~
- These are simply terms identifying the various ways
- registers, pointers and displacements, and immediate numbers may
- be combined to carry out the code operations. The 8088 language
- permits any of the following examples with most of the op codes.
- Where there are exceptions they are noted in the mnemonic table.
- Segment registers are special: see the MOV, PUSH or POP
- mnemonics. An immediate number is one which is used by itself
- as the second operand.
-
- Register, Register: mov ax,bx
- test cl,bh
- mov ax,es
- Register, Immediate: mov ax,0
- mov si,Any_Old_Label
- add ch,23
- Pointer, Register or
- Register, Pointer: mov al,[si]
- add [bx+si+03],bh
- cmp [BX+Table_1],cl
- Pointer, Immediate: movW [di],0D0Ah
- cmpB [bx],17
- xorB [bx+Table_1],7Fh
-
- Note that where a pointer is combined with a register, Lass
- knows whether the pointer is pointing to a byte or a word, but
- when there is only an immediate number, even when it is
- obviously too big for a byte, the op code mnemonic must have a B
- or a W tacked on to help the assembler.
-
- There is no pointer to pointer addressing mode in the 8088
- language.
-
- Chapter V
- Mnemonic Table
-
- Unless otherwise noted, an op code takes two operands, uses
- any of the addressing modes, and affects the flags noted in the
- right column. If no flag is marked, none is affected. To
- complement means to set a bit to 1 if 0 or to clear a bit to 0
- if it is 1. When the code LAHF or SAHF is used, it is the right
- byte of the flags register that is loaded into or stored from
- AH. Bits that are unaccounted for in the list are simply unused.
-
- left byte right byte of flags register
- Flags are: O overflow S sign
- D direction Z zero
- I interrupt A auxiliary carry
- T trap P parity
- C carry
-
- The following symbols are used to show how flags are affected:
-
- x flag is set according to the result of the operation.
- 0 flag is cleared, whatever the result.
- 1 flag is set to 1, whatever the result.
- . (period) the flag may be affected, but unpredictably.
-
- ---------
- O D I T S Z A P C
- AAA ascii adjust for addition . . . x . x
- AAD ascii adjust for division . x x . x .
- AAM ascii adjust for multiplication . x x . x .
- AAS ascii adjust for subtraction . . . x . x
-
- ADC add with carry. Adds the second x x x x x x
- operand to the first operand, then
- adds the 0 or 1 from the carry flag.
-
- ADD adds as above, but ignores the carry x x x x x x
- flag
-
- AND compares the bits of two operands. 0 x x . x 0
- If a bit in the first operand is set
- to 1, AND the same bit in the second
- operand is set to 1, that bit in the
- first operand will remain 1; any
- other bits will be set to 0. That is:
-
- mov ax,64h ;0110 0100
- and ax,0Fh ;0000 1111
- ;0000 0100 04 now in AX
-
- CALL takes a 2 byte displacement number. See JA, etc., for an
- explanation of how this number is used. It may be in
- the form of a label, held in a double register, or
- pointed to by a word pointer. An immediate number may
- also be used, if you know where the routine you are
- calling will be assembled. This is unlikely, but could
- be true if you have located it with an ORG statement.
- The displacement syntax $+/- may not be used. Since
-
- only one segment may be addressed, FAR CALLs will result
- in an error message. Remember that the offset address
- of the operation following the CALL is pushed onto the
- stack when the call is made, and must be available for
- the RETurn. Keep careful count of PUSHes and POPs. Any
- of the following addressing modes is acceptable:
-
- call Old_Hat ;label
- call BX ;double register
- call [BX+DI+03] ;can only be word pointer, so
- ;callW is not necessary
-
- The following 6 op codes take no operand; only the flag referred
- to by the code, if any, is affected.
-
- CBW Convert byte to word. Byte in question is the AL
- register; AH is set to 0, or FF if bit 7 is set.
- For this code, 8088 assumes that any number
- greater than 127 (7Fh) is negative.
- CLC Clear carry flag
- CLD Clear direction flag
- CLI Clear interrupt flag
- CMC Complement carry flag
- CWD Convert word to double word. Word in question is in
- the AX register; DX is set to 0, or FFFF if word is
- negative, that is, greater than 7FFFh
-
- O D I T S Z A P C
- CMP Compares two operands by pretending x x x x x x
- to subtract the second from the
- first, but without changing either
- operand. Action may be taken
- according to the status of the flags.
- See the jumps, and compare with TEST.
-
- CMPS Compares two strings as for CMP, by x x x x x x
- subtracting the source string,
- pointed to by DS:SI (segment and
- offset) from the destination string pointed to by ES:DI.
- Length of string must be in the CX register. SI and DI
- are incremented if the direction flag is clear (UP), or
- decremented if it is set (DN): once for CMPSB or twice
- for CMPSW.
-
- The next two codes take no operand.
- O D I T S Z A P C
- DAA Decimal adjust for addition x x x x x x
- DAS Decimal adjust for subtraction . x x x x x
-
- DEC Decrement by 1. Takes 1 operand. x x x x x
-
- DIV Divide AL by a single register or . . . . . .
- byte pointer, leaving the remainder
- in AH, or AX by a double register or
- word pointer, leaving the remainder in DX. AL or AX is
- implied, only the register or pointer is needed. AH or
- DX must hold 0 before division.
-
- DS: segment registers. Each should be on a line by itself,
- ES: preceding the op code which it affects.
- That is, instead of
-
- MOV ES:[DI],AX
-
- write on two lines
-
- ES:
- MOV [DI],AX
-
- HLT Halt. No operand. Waits for an interrupt, such as from a
- printer. Will merely hang up the computer if you try to
- use it to set break points for debugging.
-
- For the next two op codes, the numbers are
- read as signed numbers.
- O D I T S Z A P C
- IDIV Integer (signed number) division. As . . . . . .
- for DIV.
- IMUL Integer (signed number) multiplicat- x . . . . x
- ion. Otherwise as for MUL
-
- IN Input byte or word into AL or AX
- from one of 256 possible ports. Port
- number may be an immediate number or
- held in DX.
-
- INC Increment by 1. Takes one operand. x x x x x
-
- INT A call to the first "page" of DOS 0 0
- Uses a 1 byte number for address.
- INT 21h is the most used.
- INTO Interrupt if overflow flag is set to 0 0
- 1. (Calls INT 4)
- IRET Interrupt return. Restores all flags
- and POPs the CS register as well as
- IP. See RET.
-
- None of the following conditional JUMP codes affects any of the
- flags. They each take one operand, a one byte immediate signed
- number. This number is the difference (displacement) between
- the offset address of the code following the jump and the offset
- address of the destination. It is usually provided in the
- source code by a label:
-
- JC Next_Lap
-
- Since the jump may be made in either direction, the number may
- be either plus or minus and the limits are -128 and 127 (FFh and
- 7Fh). See the error message "Jump too far" for how to handle
- this error during assembly. Also note the mnemonics marked with
- an asterisk in the conditional jump table. They may not be
- used. However, there is an alternative listed for each one.
-
- You may also use the dollar symbol "$" to order Lass to use an
- immediate number as the displacement byte. In order to use this
- convention successfully you must know the number of bytes in
- each operation that you jump. Don't worry about making sense
- out of the following code, just note the way $+/- is used.
-
- cmp ax,dx <----. 2 bytes ------.
- ja $+6 =----. ; 2 bytes \
- jz $+3 =--. ; ; 2 bytes -. \
- mov ax,0 ; ; ; 3 bytes } 6 } 15
- ret <--' ; ; 1 byte -' /
- mov ax,63h <--' ; 3 bytes /
- loop $-15d =--' 2 bytes ------'
-
-
- op jump if:
- ~~~~~~~~~~~~~~~
- JA destination operand is above source operand
- JAE above or equal
- JB destination operand is below source operand
- JBE below or equal
- JC carry flag is set (to 1). Similar to JB.
- JCXZ CX is 0. (Compare to LOOP.)
- JE operands are equal. Same as JZ.
- JG dest'n operand is greater than source operand
- JGE greater than or equal. Same as JNL
- JL destination operand is less than source operand
- JLE less than or equal. Same as JNG.
- JNA destination operand is not above source operand
- JNAE* will be mistaken for JNA: use JB
- JNB destination operand is not below source operand
- JNBE* will be mistaken for JNB: use JA
- JNC carry flag is not set (to 1). Same as JNB
- JNE destination operand is not equal to source operand
- JNG destination operand is not greater than source operand
- JNGE* will be mistaken for JNG: use JL
- JNL destination operand is not less than source operand
- JNLE* will be mistaken for JNL: use JG
- JNO overflow flag is not set (to 1).
- JNP parity is odd. Same as JPO.
- JNS sign flag is not set (to 1). (positive result)
- JNZ zero flag is not set (but is 0).
- JO overflow flag is set (to 1).
- JP parity is even. Same as JPE.
- JPE parity is even.
- JPO parity is odd.
- JS sign flag is set (to 1). (negative result)
- JZ operands are equal. (Zero flag is set to 1) Same as JE.
-
- The next two jumps take no conditions for action, but otherwise
- act in the same way as the conditional jumps. JMP uses 2 bytes
- for the displacement and JMPS uses just 1 byte.
-
- JMP see CALL
- JMPS Short jump. May be used if displacement is a 1 byte
- number. May also be used with $+/-.
-
- LAHF load AH register from flags register. No operand. The
- right flag byte with S Z _ A _ P _ C is moved.
- The unnamed bits are not in use. See SAHF.
-
- LDS Sets up two registers, usually to point into another
- segment. The register, pointer mode is the only one
- permitted. For example, LDS DI,[BX+SI] loads registers
- DS and DI from the two words pointed to by the 2nd
- operand. DI is loaded from the first two bytes, DS from
- the last two.
-
- LEA load effective address
- LES As for LDS, using the ES segment register. If 0007 were
- stored at Video_Addr and B000 in the next word then LES
- AX,[Video_Addr] would point ES to the black and white
- screen memory segment and set 0700 into AX.
-
- LOCK lock bus. No operand.
-
- LODS loads AL or AX with string pointed to by DS:SI (segment
- and offset). No operands, but B or W must be added
- (LODSB or LODSW). SI is incremented if direction flag
- is clear (UP) or decremented if flag is set (DN).
-
- One operand, the displacement number, for LOOP operations. Uses
- the same rules as conditional jumps, including use of $+/-.
-
- LOOP decrements CX and jumps if CX is not 0. See JCXZ.
- LOOPE dec's CX and jumps if CX is not 0 and zero flag is set
- LOOPZ same as LOOPE
- LOOPNE dec's CX and jumps if CX is not 0 and zero flag is clear
- LOOPNZ same as LOOPNE
-
- MOV load the destination with the contents of the source.
- Any addressing mode may be used. In addition, segment
- registers may be used for pointer to register MOV's or
- register to register - if one register is NOT a segment
- register. Flags unchanged.
-
- MOVS move byte or word string from the source pointed to by
- DS:SI (segment and offset) to destination pointed to by
- ES:DI. SI and DI are incremented if the direction flag
- is clear (UP), or decremented if it is set (DN): once
- for MOVSB or twice for MOVSW. Usually used with REP.
- Since moving a message line to the screen calls for two
- increments to DI and MOV [DI],AX, but just one increment
- for SI and MOV AL,[SI] this block move cannot be used.
-
-
- O D I T S Z A P C
- MUL multiply AL by a single register or x . . . . x
- byte pointer, or AX by a double
- register or word pointer. Since AL
- or AX is implied by the op, only one operand is needed.
- The result is found in AX or in AX and DX. AH or DX
- will be cleared by the operation and if no overflow
- occurs will remain at 0.
-
- O D I T S Z A P C
- NEG change a positive number to negative, x x x x x 1
- or a negative number to positive.
- Takes one operand.
-
- NOP no operation. Takes one byte. Can be used to make room
- in a program for possible changes during debugging, or
- to remove code temporarily that you wish to skip until
- debugging is finished.
-
- NOT reverses each bit in operand. That is:
-
- if AL holds 0101 0011
- NOT AL holds 1010 1100
- O D I T S Z A P C
- OR compare the bits of two operands. If 0 x x . x 0
- a bit in the first operand is set to
- 1, OR the same bit in the second
- operand is set to 1, that bit in the result (in the
- first operand) will be set to 1. Only bits which are 0
- in both operands will be 0 in the result.
-
- mov ax,64h ;0110 0100
- or ax,4Fh ;0100 1111
- ;0110 1111 6Fh now in AX
-
- OUT output byte or word from AL or AX to one of 256 possible
- ports. Port number may be an immediate number or held in
- DX. That is: OUT DX,AL or OUT 61,AX.
- POP pop word off stack into double register (including
- segment registers) or word pointer.
- POPF pop word off stack into flags register. All flags, of
- course, will be reset to value previously stored.
- PUSH push word from double register (including segment
- register) or word pointer onto stack.
- PUSHF push flags onto stack. Flags remain unchanged.
-
- REP repeat a string operation such as MOVSB, until CX is 0.
- Decrements CX. Takes no operand and affects no flags.
- REP must be on a line by itself.
-
- rep movsw ;WRONG. Movsw will be lost
-
- REP ;RIGHT
- MOVSB
-
- REPE as for REP, but will end operation if zero flag is
- cleared; for instance if 2 bytes being compared are not
- equal.
- REPZ same as REPE
- REPNE as for REP, but will end operation if zero flag is set.
- REPNZ same as REPNE
- RET causes a return to the offset address on the stack.
- Usually this address was placed there by a CALL.
- RETF Since a program that will be called from another program,
- such as one written in Basic, needs a far return at the
- end, RETF is recognized.
-
- The next six op codes each take two operands, a register or a
- pointer, and 1 or CL. 1 indicates that the operation is to be
- performed once; CL holds the number of repeats. In each case,
- each bit in the operand is moved over one place (for one
- operation) in the direction indicated, and the overflow bit goes
- to the carry flag.
-
- For a shift, the empty bit is replaced with 0. (But see SAR.)
- For a rotate, the empty bit is replaced either with the bit
- shoved off the other end (ROL, ROR) or with the bit already in
- the carry flag (RCL,RCR).
- O D I T S Z A P C
- RCL rotate left through carry flag. x x
- RCR rotate right through carry flag. x x
- ROL rotate left, bit 7 into bit 0 x x
- ROR rotate right, bit 0 into bit 7 x x
- SHL shift left, 0 into bit 0 x x
- SHR shift right, 0 into bit 7 x x
- SAR shift arithmetic right. The leftmost x x
- bit is shifted with the others but
- is not replaced. It remains in bit 7,
- maintaining sign of number. If enough SAR's are done,
- any negative number will become FFFF (or -1) and any
- positive number will become 0.
- O D I T S Z A P C
- SAHF store contents of AH register in the x x x x x
- right half of flags register. The
- flags are stored as S Z . A . P . C
- with bits 1, 3, and 5 unused and
- having no effect. See LAHF.
- SBB subtract with borrow. Subtracts the x x x x x x
- second operand from the first
- operand and also subtracts the 0 or
- 1 that is in the carry flag
- SUB subtracts as above, but ignores the x x x x x x
- carry flag
- TEST performs an AND operation without 0 x x . x 0
- changing either operand. Can be used
- to compare for 2 numbers at the same
- time, such as 2 or 8 by TEST AL,0Ch. If either number
- is found, the zero flag is set to 1 (non_zero). See CMP.
- WAIT wait while test pin not asserted. No operand.
- XCHG exchanges the two operands. One operand must be a
- register, the other may be a register or a pointer.
- XLAT adds the contents of the AL register to the contents of
- the BX register and then moves the contents of the byte
- pointed to by BX into the AL register.
-
- that is, mov BX,Table
- mov AL,02
- XLAT
-
- performs like mov BX,Table
- mov AX,02
- add BX,AX
- mov AL,[BX]
-
- XLAT can be used to find one character in an array. When
- the character is found, BX will point to it in the table.
- For instance:
-
- mov BX,Table-02
- Table_Loop mov AL,02
- XLAT
- cmp al,dl
- jz Out_of_Loop ;BX points to char
- loop Table_Loop
-
- O D I T S Z A P C
- XOR The exclusive OR. Compares the bits 0 x x . x 0
- of the two operands. Similar to OR
- except that a bit in the result is
- set to 1 only if one but not both operand bits hold 1.
- If they match, both holding 1 (or 0, of course) that bit
- in the result is set to 0.
-
- mov ax,10h ;0001 0000
- xor ax,10h ;0001 0000
- ;0000 0000 0 now in AX
- but
- mov ax,40h ;0100 0000
- xor ax,10h ;0001 0000
- ;0101 0000 50h now in AX
-
- Chapter VI
- Pseudo Op Codes
-
- There is also a group of operations which give instructions
- to Lass but do not appear in the final object code. Hence the
- term 'pseudo'. Some which are needed for .EXE assembly are not
- needed by Lass for .COM programs. If they occur in your source
- code they will simply be ignored. A list of all that Lass
- recognizes follows.
-
- Assume ignored. When a .COM program is loaded by DOS, all
- segment registers are set to the same value. If you
- change any of them within your program it is up to you
- to keep track and return them to the code segment as
- needed.
-
- DB define byte. This code tells Lass to put one or more
- byte values into the object code. If there are too many
- bytes in your series or string to fit on one source code
- line, you must continue on the next line with another
- DB. There does not have to be a label in front of DB.
- They may all be ascii characters inside one pair of
- single quotes, forming a string, or they may be a series
- of individual numbers. A series may be any mix of
- decimal, hexadecimal or ascii values, separated by
- commas. Be careful not to use ' within a string. The
- reverse quote, (`) may be used, or the double quote ("),
- but the normal single quote will terminate a string.
-
- If the first operand is a number N and it is followed
- not by a comma but by spaces and another number or ascii
- character in parentheses, a block of code will be filled
- with N characters. See examples below.
-
- There are two limitations for a series:
-
- If the first operand is an ascii character, it must be
- just a single character. Otherwise the line will be
- translated as a string. Any following operand may
- include more than one character between pairs of ''.
- There must be no space between a number and its
- following comma. A vagrant space would cause Lass to
- think it had found the end of the line. Examples:
-
- Series DB 'A',65,49h,'AIA'
- Just_One DB 33h
- Table DB 1,2,3, 4,5 ;spaces AFTER a comma ok
- DB 235, 245, 255 ;255 is maximum for a byte
- Filler DB 10h (0) ;fills 16 bytes with zeros
- DB 10h ('0') ;now with 16 ascii zeros (30h)
- DB 10h ('ABC') ;fills 48 bytes with ABCABC, etc.
- Message_String:
- DB 'Any length to the end of the line is acc'
- DB 'epted. If the final apostrophe is not present'
- DB ' the message will include ;all else on line
-
- DW define word. Essentially the same as DB, but no ascii
- characters are accepted. See Filler examples for DB.
- Examples for DW:
-
- Words DW 4941h, 0,23 ;each number will fill 2 bytes
- Filler DW 10h (0) ;fills 32d bytes with zeros
-
- Note that Lass does not care whether you have stored a
- number as a byte or as a word, and will not warn you if
- you remove a word where you stored a byte or vice versa.
-
- END ignored
-
- EQU sets a value to a label. The label must be present and
- on the same line. The value must be no greater than
- 65,535 (FFFFh) so it can be contained in one word.
- Examples:
-
- SCREEN equ 0B800h ;one word
- Keyboard_Call equ 21h ;one byte
- Big_Letter equ 'A'
- Letter_Plus equ Big_Letter+20h
-
- but the following are NOT acceptable:
-
- Keyboard_Call:
- equ 21h ;label must be on same line
- Value equ 70000h ;too large for one word
-
- In addition, it is recommended that all EQU statements
- be placed at the beginning of the program, or errors may
- result. See LABEL discussion for a fierce warning.
- Data is often placed with the EQU statements, to form a
- reference block where it easy to find. This causes a
- small conflict since the first code byte must also be at
- the beginning of the program. No real problem, just
- start the program with a jump over the data to the
- beginning of the code. For instance:
-
- JMP Work_Starts ;your program code
-
- Name equ 5 ;place all EQU statements first
- Height equ 10
- Varbl_1 db 0 ;now your data block
- Table db 0,1,2,3 ;etc., etc., etc.
-
- Work_Starts:
- push DS ;and so forth
-
- ORG origin. Forces the next code byte to be at the offset
- address given in the one operand. All bytes between the
- current object code byte and the origin byte will be
- filled with zeros. If there are too many code bytes
- already assembled, Lass will tell you so you can revise
- the origin address.
-
- PROC ignored
-
-
-